package com.jjc.android.base

import android.content.Context
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.Nullable
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import com.jjc.android.R
import com.jjc.android.view.status.OnStatusChildClickListener
import com.jjc.android.view.status.StatusLayoutManager
import com.lzy.okgo.OkGo
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import org.greenrobot.eventbus.EventBus
import java.io.Serializable

abstract class BaseFragment : Fragment() {

    private var compositeDisposable: CompositeDisposable? = null

    protected fun addDisposable(disposable: Disposable){
        if(compositeDisposable==null){
            compositeDisposable = CompositeDisposable()
        }
        compositeDisposable?.add(disposable)
    }

    private fun destroyDisposable(){
        if(compositeDisposable!=null&&!compositeDisposable!!.isDisposed){
            compositeDisposable?.dispose()
        }
    }

    @JvmField
    var rootView: View? = null
    protected abstract fun getLayoutId(): Int

    /**
     * 初始化控件
     */
    protected open fun initView(view: View){
        if (isHaveEventBus()) {
            if (!EventBus.getDefault().isRegistered(this)) {
                EventBus.getDefault().register(this)
            }
        }
    }
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (rootView == null) {
            rootView = onCreateView(inflater, container)
        } else {
            val parent = rootView?.parent as? ViewGroup
            parent?.removeView(rootView)
        }
        initView(rootView!!)
        return rootView
    }

    @JvmField
    protected var mContext: Context? = null
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        mContext = activity

    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        mContext = activity
    }

    protected fun onCreateView(inflater: LayoutInflater, container: ViewGroup?): View {
        return onLayoutInflaterView(inflater, container)
    }

    protected open fun onLayoutInflaterView(inflater: LayoutInflater, parentView: ViewGroup?): View {
        return inflater.inflate(getLayoutId(), parentView, false)
    }

    protected fun showLoadingDialog() {
        if (context != null && context is BaseActivity) {
            (context as BaseActivity).showLoadingDialog()
        }
    }

    protected fun hideLoadingDialog() {
        if (context != null && context is BaseActivity) {
            (context as BaseActivity).hideLoadingDialog()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        destroyDisposable()
        OkGo.getInstance().cancelTag(this)
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
    }

    protected open fun isHaveEventBus(): Boolean {
        return false
    }

    /**
     * Fragment的添加
     * @param aClass 相应的Fragment对象的getClass
     * @param containerId 容器的id
     * @param args 需要传值的话可将bundle填入  不需要传值就填null
     */
    protected open fun addFragment(aClass: Class<out BaseFragment?>, containerId: Int, args: Bundle? = null) {
        addFragment(aClass,containerId,null,
            inflateLazy = false,
            isNeedToAddBackStack = false,
            args = args
        )
    }


    protected open fun addFragment(aClass: Class<out BaseFragment?>, containerId: Int ,animResArray: Array<Int>?=null,inflateLazy:Boolean = false,isNeedToAddBackStack:Boolean = false, args: Bundle? = null) : Fragment?{
        val manager: FragmentManager = childFragmentManager
        val tag = aClass.name
        var fragment: Fragment? = manager.findFragmentByTag(tag)
        val transaction: FragmentTransaction = manager.beginTransaction()
        val findFragment = fragment!=null
        if (fragment == null) { // 没有添加
            try {
                fragment = aClass.newInstance()
                (fragment as? BaseLazyLoadFragment)?.setInflateLazy(inflateLazy)
                // 设置 fragment 进入，退出， 弹进，弹出的动画
                if(animResArray!=null&&animResArray.size>=4){
                    transaction.setCustomAnimations(animResArray[0], animResArray[1], animResArray[2], animResArray[3])
                }
                transaction.add(containerId, fragment!!, tag)
                if (isNeedToAddBackStack) { // 判断是否需要加入回退栈
                    transaction.addToBackStack(tag) // 加入回退栈时制定一个tag，以便在找到指定的事务
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        } else {
            if (fragment.isAdded) {
                if (fragment.isHidden) {
                    transaction.show(fragment)
                }
            } else {
                transaction.add(containerId, fragment, tag)
            }
        }
        if (fragment != null) {
            if(args!=null&&!findFragment){
                fragment.arguments = args
            }
            hideBeforeFragment(manager, transaction, fragment)
            transaction.commitAllowingStateLoss()
        }
        return fragment
    }

    /**
     * 除当前 fragment 以外的所有 fragment 进行隐藏
     *
     * @param manager
     * @param transaction
     * @param currentFragment
     */
    protected fun hideBeforeFragment(manager: FragmentManager, transaction: FragmentTransaction, currentFragment: Fragment) {
        val fragments: List<Fragment> = manager.fragments
        for (fragment in fragments) {
            if (fragment !== currentFragment && !fragment.isHidden) {
                transaction.hide(fragment)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (arguments != null) {
            setupArguments(arguments);
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        onSaveIntent(outState)
        super.onSaveInstanceState(outState)
    }


    protected open fun onSaveIntent(savedInstanceState: Bundle) {
        if (arguments != null) {
            val bundle = arguments
            if (bundle != null) {
                val keySet = bundle.keySet()
                for (key in keySet) {
                    val value = bundle[key]
                    if (value != null) {
                        when(value){
                            is String -> savedInstanceState.putString(key, value)
                            is Int -> savedInstanceState.putInt(key, value)
                            is Boolean -> savedInstanceState.putBoolean(key, value)
                            is Float -> savedInstanceState.putFloat(key, value)
                            is Long -> savedInstanceState.putLong(key, value)
                            is Parcelable -> savedInstanceState.putParcelable(key, value)
                            is Serializable -> savedInstanceState.putSerializable(key, value)
                            else-> savedInstanceState.putString(key, value.toString())
                        }
                    }
                }
            }
        }
    }

    override fun onViewStateRestored(@Nullable savedInstanceState: Bundle?) {
        super.onViewStateRestored(savedInstanceState)
        savedInstanceState?.let { setupArguments(it) }
    }

    protected open fun fetchPageInfo(){

    }

    private var statusLayoutManager: StatusLayoutManager? = null

    fun showLoadingView(wrapperView:View,emptyText:String = getString(R.string.status_layout_manager_empty)){
        if(statusLayoutManager==null){
            statusLayoutManager = StatusLayoutManager.Builder(wrapperView)
                .setDefaultEmptyText(emptyText)
                .setDefaultEmptyClickViewVisible(false)
                .setDefaultErrorClickViewVisible(false)
                .setOnStatusChildClickListener(object : OnStatusChildClickListener {
                    override fun onEmptyChildClick(view: View?) {
                        fetchPageInfo()
                    }

                    override fun onErrorChildClick(view: View?) {
                        fetchPageInfo()
                    }

                    override fun onCustomerChildClick(view: View?) {
                        fetchPageInfo()
                    }
                })
                .build()
        }
        statusLayoutManager?.showLoadingLayout()
    }

    fun hideLoadingView(){
        statusLayoutManager?.showSuccessLayout()
    }

    fun showEmptyView(emptyText:String = getString(R.string.status_layout_manager_empty)){
        statusLayoutManager?.showEmptyLayout(emptyText)
    }

    fun showErrorView(errorText:String? = getString(R.string.net_error_txt)){
        statusLayoutManager?.showErrorLayout(errorText)
    }

    protected open fun setupArguments(args: Bundle?) {}
}